package com.example.config;

import java.util.EnumSet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.listener.StateMachineListener;
import org.springframework.statemachine.listener.StateMachineListenerAdapter;
import org.springframework.statemachine.transition.Transition;

import com.example.constants.Events;
import com.example.constants.States;

/**
 * 状态机配置
 * 
 * @author lli
 *
 * @version 1.0
 *
 */
@Configuration
@EnableStateMachine
public class StateMachineConfig extends
        EnumStateMachineConfigurerAdapter<States, Events> {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public void configure(StateMachineStateConfigurer<States, Events> states)
        throws Exception {
        // 定义状态机中的状态
        states.withStates().initial(States.UNPAID)// 初始状态
                .states(EnumSet.allOf(States.class));// 指定所有状态
    }

    @Override
    public void configure(
            StateMachineTransitionConfigurer<States, Events> transitions)
        throws Exception {
        transitions.withExternal().source(States.UNPAID)
                .target(States.WAITING_FOR_RECEIVE)
                // 指定状态来源和目标
                .event(Events.PAY)
                // 指定触发事件
                .and().withExternal().source(States.WAITING_FOR_RECEIVE)
                .target(States.DONE).event(Events.RECEIVE);
    }

    @Override
    public void configure(
            StateMachineConfigurationConfigurer<States, Events> config)
        throws Exception {
        config.withConfiguration().machineId("状态机1号").autoStartup(true)
                .listener(listener());// 自动开启状态机
    }

    @Bean
    public StateMachineListener<States, Events> listener() {
        return new StateMachineListenerAdapter<States, Events>() {
            @Override
            public void transition(Transition<States, Events> transition) {
                if (States.UNPAID.equals(transition.getTarget().getId())) {
                    logger.info("订单创建，待支付");
                    return;
                }
                if (States.UNPAID.equals(transition.getSource().getId())
                        && States.WAITING_FOR_RECEIVE.equals(transition
                                .getTarget().getId())) {
                    logger.info("用户完成支付，待收货");
                    return;
                }
                if (States.WAITING_FOR_RECEIVE.equals(transition.getSource()
                        .getId())
                        && States.DONE.equals(transition.getTarget().getId())) {
                    logger.info("用户已收货，订单完成");
                    return;
                }
            }
        };
    }

}